/**
 * 
 */
package info.niwota.group.thread;

import info.niwota.group.Constants;
import info.niwota.group.thread.Topic.Threads;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

/**
 * @author qiangli
 *
 */
public class TopicProvider extends ContentProvider {

	private static final String DATABASE_NAME = "topics.db";
	
	private static final String TOPIC_TABLE = "threads";

	private static final String CREATE_SQL = "CREATE TABLE " + TOPIC_TABLE
	+ " (" + Threads._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
	+ Threads.NAME + " TEXT COLLATE LOCALIZED," + Threads.EMAILS + " TEXT,"
	+ Threads.TITLE + " TEXT COLLATE LOCALIZED NOT NULL," + Threads.BODY + " TEXT,"
	+ Threads.ATTACHMENT + " TEXT,"
	+ Threads.PHOTO + " TEXT,"
	+ Threads.RINGTONE + " TEXT,"
	+ Threads.STARRED
	+ " INTEGER NOT NULL DEFAULT 0,"
	+ Threads.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0,"
	+ Threads.LAST_TIME_CONTACTED + " INTEGER,"  
	+ Threads.CREATED_DATE +" INTEGER,"
	+ Threads.MODIFIED_DATE +" INTEGER,"
	+ Threads.DATA1 + " TEXT," + Threads.DATA2
	+ " TEXT," + Threads.DATA3 + " TEXT," + Threads.DATA4 + " TEXT,"
	+ Threads.DATA5 + " TEXT, UNIQUE (" + Threads.NAME + ") );";

	private static final String TAG = "TopicProvider";
	
	
	private static class DatabaseHelper extends SQLiteOpenHelper {
		public DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			if (Constants.DEBUG_ENABLED) {
				Log.d(TAG, "create db");
			}
			db.execSQL(CREATE_SQL);
			db.execSQL("CREATE INDEX topicNameIndex ON " + TOPIC_TABLE + " ("
					+ Threads.NAME + ");");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			//
		}
	}

	private static final int DATABASE_VERSION = 1;

	private static final int TOPIC_NAME = 2;
	
	private static final int TOPIC_SEARCH = 3;
	
	private static final int TOPICS = 1;
	
	private static HashMap<String, String> TOPICS_LIST_PROJECTION_MAP;

	private static final UriMatcher URI_MATCHER;

	static {
		URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
		URI_MATCHER.addURI(Topic.AUTHORITY, "threads", TOPICS);
		URI_MATCHER.addURI(Topic.AUTHORITY, "threads/*",
				TOPIC_NAME);
		URI_MATCHER.addURI(Topic.AUTHORITY, "threads/search/*",
				TOPIC_SEARCH);
		//
		TOPICS_LIST_PROJECTION_MAP = new HashMap<String, String>();
		TOPICS_LIST_PROJECTION_MAP.put(Threads._ID, "_id");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.NAME, "name");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.EMAILS, "emails");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.TITLE, "title");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.BODY, "body");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.PHOTO, "photo");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.CREATED_DATE, "created");
		TOPICS_LIST_PROJECTION_MAP.put(Threads.MODIFIED_DATE, "modified");
	}

	private DatabaseHelper dbHelper;

	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		int count;
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		switch (URI_MATCHER.match(uri)) {
		case TOPICS:
			count = db.delete(TOPIC_TABLE, where, whereArgs);
			break;
		case TOPIC_NAME:
			if (!TextUtils.isEmpty(where) || (whereArgs != null)) {
				throw new UnsupportedOperationException(
						"Cannot use where clause");
			}
			String topicId = uri.getPathSegments().get(1);
			count = db.delete(TOPIC_TABLE, "_id=?", new String[] { topicId });
			break;
		default:
			throw new IllegalArgumentException("Unknown URL " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch (URI_MATCHER.match(uri)) {
		case TOPICS:
		case TOPIC_SEARCH:
			// for a notes list, or search results, return a mimetype
			// indicating
			// a directory of notes
			return "vnd.android.cursor.dir/vnd.etalk.topic";
		case TOPIC_NAME:
			return "vnd.android.cursor.item/vnd.etalk.topic";
		default:
			throw new IllegalArgumentException("Unknown URL " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {
		long rowid = 0;
		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		// We can only insert a note, no other URLs make sense here
		if (URI_MATCHER.match(uri) != TOPIC_NAME) {
			throw new IllegalArgumentException("Unknown URL " + uri);
		}
		//
		Long now = Long.valueOf(System.currentTimeMillis());

		//
		if (values.containsKey(Threads.CREATED_DATE) == false) {
			values.put(Threads.CREATED_DATE, now);
		}

		if (values.containsKey(Threads.MODIFIED_DATE) == false) {
			values.put(Threads.MODIFIED_DATE, now);
		}

		if (values.containsKey(Threads.NAME) == false) {
			values.put(Threads.NAME, uri.getLastPathSegment());
		}
		
		if (values.containsKey(Threads.EMAILS) == false) {
			values.put(Threads.EMAILS, "");
		}
		
		if (values.containsKey(Threads.TITLE) == false) {
			values.put(Threads.TITLE, "");
		}

		if (values.containsKey(Threads.BODY) == false) {
			values.put(Threads.BODY, "");
		}

		SQLiteDatabase db = dbHelper.getWritableDatabase();
		rowid = db.insert(TOPIC_TABLE, "body", values);
		
		if (rowid > 0) {
			Uri newUri = Uri.withAppendedPath(Topic.ALL_TOPICS_URI, Long.toString(rowid));
			getContext().getContentResolver().notifyChange(newUri, null);
			if (Constants.DEBUG_ENABLED) {
				Log.d(TAG, "inserted uri: " + newUri);
			}
			return newUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	@Override
	public boolean onCreate() {
		dbHelper = new DatabaseHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sort) {
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		String[] whereArgs = null;

		switch (URI_MATCHER.match(uri)) {
		case TOPICS:
			qb.setTables(TOPIC_TABLE);
			qb.setProjectionMap(TOPICS_LIST_PROJECTION_MAP);
			break;
		case TOPIC_SEARCH:
			qb.setTables(TOPIC_TABLE);
			qb.setProjectionMap(TOPICS_LIST_PROJECTION_MAP);
			qb.appendWhere(Threads.BODY +" like ? or " + Threads.TITLE + " like ? ");
			whereArgs = new String[2];
			whereArgs[0] = whereArgs[1] = "%" + uri.getLastPathSegment() + "%";
			break;
		case TOPIC_NAME:
			qb.setTables(TOPIC_TABLE);
			qb.appendWhere(Threads.NAME + " = ?");
			whereArgs = new String[] { uri.getLastPathSegment() };
			break;
		default:
			throw new IllegalArgumentException("Unknown URL " + uri);
		}

		//
		String orderBy;
		if (TextUtils.isEmpty(sort)) {
			orderBy = Topic.DEFAULT_SORT_ORDER;
		} else {
			orderBy = sort;
		}

		//
		SQLiteDatabase mDb = dbHelper.getReadableDatabase();
		Cursor c = qb.query(mDb, projection, null, whereArgs, null, null,
				orderBy);
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	@Override
	public int update(Uri uri, ContentValues values, String where,
			String[] whereArgs) {
		int count;
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		switch (URI_MATCHER.match(uri)) {
		case TOPICS:
			count = db.update(TOPIC_TABLE, values, where, whereArgs);
			break;
		case TOPIC_NAME:
			values.put(Threads.MODIFIED_DATE, System
							.currentTimeMillis());
			count = db.update(TOPIC_TABLE, values, where, whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URL " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

}
